package com.yazdankhah.dal;

import com.yazdankhah.utils.GenUtil;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;

/**
 *
 * @author ahmad
 * @param <E> The type parameter represents the database objects.
 */
public class AYSql<E> {
  
  private String sqlStr;
  private final Class<? extends E> c;
  private E bean;
  private final Object[] varArr;
  
  private static final Logger logger = Logger.getLogger(AYSql.class);
  

  public AYSql(String sqlStr, Object... varArr) {
    this.sqlStr = sqlStr;
    this.c = null;
    this.varArr = varArr;
  } //constructor
  
  
  public AYSql(String sqlStr, Class<? extends E> c, Object... varArr) {
    this.sqlStr = sqlStr;
    this.c = c;
    this.varArr = varArr;
  } //constructor
  
  
  public AYSql(E bean, Class<? extends E> c, Object... varArr) {
    this.bean = bean;
    this.c = c;
    this.varArr = varArr;
  } //constructor
  
  
  
  
  public <E> List<E> getBeansList() {
    
    DalSession dSession = DalSession.getDalSession();
    Connection conn = dSession.getDSConnection();
    
    if (conn == null) {
      logger.error("Connection is null! Couldn't get a connection from datasource!");
      return new ArrayList<>(0);
    }
    //logger.debug("The sqlStr = [" + sqlStr + "]");
    List<E> tempList = (List<E>) SqlUtil.getBeans(conn, sqlStr, c, varArr);
    
    //GenUtil.showArrayList(tempList);
    
    dSession.closeConnection(conn);
    
    return tempList;
    
  } //method
  

  public <E> E getBean() {
    
    DalSession dSession = DalSession.getDalSession();
    Connection conn = dSession.getDSConnection();
    
    if (conn == null) {
      logger.error("Connection is null! Couldn't get a connection from datasource!");
      return null;
    }
    //logger.debug("The sqlStr = [" + sqlStr + "]");
    E bean = (E) SqlUtil.getBean(conn, sqlStr, c, varArr);
    
    //GenUtil.showArrayList(tempList);
    
    dSession.closeConnection(conn);
    
    return bean;
    
  } //method
  

  /**
   * Deletes a bean from the database.
   * @param isTransaction - if this deletion is part of a transaction, this is true.
   * @return true if the delete operation is successful, false otherwise
   */
  public boolean delete(boolean isTransaction) {
    
    DalSession dSession = DalSession.getDalSession();
    Connection conn = dSession.getDSConnection();
    
    if (conn == null) {
      logger.error("Connection is null! Couldn't get a connection from datasource!");
      return false;
    }
    
    if (bean == null) {
      logger.error("The bean is null! Deletion operation cannot be completed!");
      return false;
    }
    
    boolean result = SqlUtil.deleteBean(conn, bean);
    
    if (!isTransaction)
      dSession.closeConnection(conn);
    
    return result;
  } //method
  
  /**
   * Inserts a bean into the database.
   * @param isTransaction - if this insert is part of a transaction, this is true.
   * @return true if the insert operation is successful, false otherwise
   */
  public boolean insert(boolean isTransaction) {
    
    DalSession dSession = DalSession.getDalSession();
    Connection conn = dSession.getDSConnection();
    
    if (conn == null) {
      logger.error("Connection is null! Couldn't get a connection from datasource!");
      return false;
    }
    
    if (bean == null) {
      logger.error("The bean is null! Insertion operation cannot be completed!");
      return false;
    }
    
    boolean result = SqlUtil.insertBean(conn, bean);
    
    if (!isTransaction)
      dSession.closeConnection(conn);
    
    return result;
  } //method
  

  /**
   * Executes a AYSql statement regardless of its content.
   * @param isTransaction - if this statement is part of a transaction, this should be true
   * @return true if the execution is successful, and false otherwise
   */
  public boolean executeDDL(boolean isTransaction) {
    
    DalSession dSession = DalSession.getDalSession();
    Connection conn = dSession.getDSConnection();
    
    if (conn == null) {
      logger.error("Connection is null! Couldn't get a connection from datasource!");
      return false;
    }
    
    if (sqlStr.isEmpty()) {
      logger.error("The SQL statement string is null! Execution operation cannot be completed!");
      return false;
    }
    
    int result = SqlUtil.executeUpdate(conn, sqlStr, varArr);
    
    if (!isTransaction)
      dSession.closeConnection(conn);
    
    return result != -1;
  }


  public String getSqlStr() {
    return sqlStr;
  }


  public void setSqlStr(String sqlStr) {
    this.sqlStr = sqlStr;
  }
  
} //class
